// --------------------------------
// <copyright file="TableDefinition.cs" company="TRONSoft">
//     Copyright (c) TRONSoft.
// </copyright>
// <license>
//   This source code is subject to terms and conditions of the Microsoft
//   Public License. A copy of the license can be found in the License.html
//   file at the root of this distribution. If you cannot locate the
//   Microsoft Public License, please send an email to dlr@microsoft.com.
//   By using this source code in any fashion, you are agreeing to be bound 
//   by the terms of the Microsoft Public License. You must not remove this
//   notice, or any other, from this software.
// </license>
// <author>Tron</author>
// ---------------------------------

using System;
using System.Data;
using System.IO;
using Microsoft.VisualBasic.FileIO;

namespace Tronsoft.Actucal.Tables
{
    public class TableDefinition
    {
        private readonly DataTable table;

        public TableDefinition(DataTable table)
        {
            if (table == null) throw new ArgumentNullException("table");

            this.table = table;
        }

        public TableColumnCollection Columns
        {
            get { return new TableColumnCollection(table.Columns); }
        }

        public string TableName
        {
            get { return table.TableName; }
        }

        public TableRowCollection Rows
        {
            get { return new TableRowCollection(table.Rows); }
        }

        public object this[int rowIndex, string columnName]
        {
            get { return table.Rows[rowIndex][columnName]; }
        }

        public object this[int rowIndex, int columnIndex]
        {
            get { return table.Rows[rowIndex][columnIndex]; }
        }

        public void AddTableRow(params object[] columns)
        {
            if (columns == null) throw new ArgumentNullException("columns");
            if ((null == table.Columns) || (table.Columns.Count == 0))
                throw new TablesException("No colums defined. Define columns before adding a row.");
            if (table.Columns.Count < columns.Length)
                throw new TablesException("Cannot add the data. Adding to much data.");

            if (0 == columns.Length)
                return;

            try
            {
                table.Rows.Add(columns);
                table.AcceptChanges();
            }
            catch (Exception ex)
            {
                throw new TablesException("Error adding data.", ex);
            }
        }

        public void AddTableRows(TextReader tableData, bool isFirstRowColumnNames, IFormatProvider provider)
        {
            if (tableData == null) throw new ArgumentNullException("tableData");
            if ((null == table.Columns) || (table.Columns.Count == 0))
                throw new TablesException("No colums defined. Define columns before adding a row");

            TextFieldParser parser = new TextFieldParser(tableData);
            parser.CommentTokens = new string[] {"#"};
            parser.Delimiters = new string[] {","};

            if (isFirstRowColumnNames)
            {
                try
                {
                    parser.ReadLine();
                }
                catch (Exception ex)
                {
                    throw new TablesException("Error reading column header.", ex);
                }
            }

            while (!parser.EndOfData)
            {
                DataRow newRow = table.NewRow();
                string[] fields = parser.ReadFields();

                if (table.Columns.Count < fields.Length)
                    throw new TablesException("Cannot add the data. Adding to much data.");

                for (int i = 0; i < fields.Length; i++)
                {
                    newRow[i] = Convert.ChangeType(fields[i], table.Columns[i].DataType, provider);
                }
                table.Rows.Add(newRow);
            }

            table.AcceptChanges();
        }

        public void Clear()
        {
            table.Clear();
        }
    }
}